#include <iostream>
#include <memory>
/**
 * @brief 练习对智能指针的使用
 * 语法： s_reportMethod.reset(new ReportMethod(reportMethod));表明s_reportMethod原来指向的智能指针被释放
 * 同时新new出来的对象被智能指针所持有：https://en.cppreference.com/w/cpp/memory/shared_ptr/reset
 * 
 */
struct AStruct;
struct BStruct;
struct AStruct
{
    std::shared_ptr <BStruct> bp;
    ~AStruct(){
        using std::cout;
        using std::endl;
        cout << "AStruct @ "<< this << " dealloc ..." << endl;
    }
};

struct BStruct
{
    // 这里要用std::weak_ptr才会解除循环引用问题
    std::weak_ptr <AStruct> ap;
    ~BStruct(){
        using std::cout;
        using std::endl;
        cout << "BStruct dealloc ..." << endl;
    }
};

void use_shared_prt(){
     using namespace std;
    {
        AStruct *noSmart = new AStruct;
        cout << "test shared pointer ..." << endl;
        // 如果不用智能指针，那么就需要对new完的对象做delete处理
        std::shared_ptr <AStruct> aS(new AStruct);
        std::shared_ptr <BStruct> bS(new BStruct);
        aS->bp = bS;
        bS->ap = aS;
        cout << "Exist current context ..." << endl;
        /*
         输出的数据如下:
           test shared pointer ...
           Exist current context ...
           AStruct dealloc ...
           BStruct dealloc ...
           Exit main
        */
    }
    cout << "Exit main" << endl;
}

void use_shared_reset() 
{
    std::shared_ptr<AStruct> as = std::make_shared<AStruct>();
    std::shared_ptr<AStruct> bs = as;
    std::shared_ptr<AStruct> cs = bs;
    using std::cout;
    using std::endl;
    cout << "as use_count: " << as.use_count() << endl;
    cout << "after reset ..." << endl;
    as.reset(new AStruct());
    cout << "as use_count: " << as.use_count() << endl;
    cout << "bs use_count: " << bs.use_count() << endl;
    /**
     * 输出的结果是:
        as use_count: 3
        after reset ...
        as use_count: 1
        bs use_count: 2
        AStruct @ 0x600002828288 dealloc ...
        AStruct @ 0x60000242c040 dealloc ...
     * 
     */
}

int main_shared_ptr()
{
//    use_shared_prt();
    use_shared_reset();
    return 0;
}
